package cn.hiapi.shopkeeper.service.activity;

import cn.hiapi.basic.ResUtils;
import cn.hiapi.basic.entity.BasicEntity;
import cn.hiapi.basic.exception.BasicException;
import cn.hiapi.basic.jpa.pageable.QueryWrapper;
import cn.hiapi.basic.redis.service.RedisService;
import cn.hiapi.basic.token.Token;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.shop.service.product.ProductNumService;
import cn.hiapi.shopkeeper.consts.AppConst;
import cn.hiapi.shopkeeper.entity.activity.Activity;
import cn.hiapi.shopkeeper.entity.activity.ActivitySolitaire;
import cn.hiapi.shopkeeper.entity.activity.ActivitySolitaireItem;
import cn.hiapi.shopkeeper.entity.order.ActivityOrder;
import cn.hiapi.shopkeeper.enums.ActivityType;
import cn.hiapi.shopkeeper.jpa.activity.ActivitySolitaireJpa;
import cn.hiapi.shopkeeper.request.CreateOrderRequest;
import cn.hiapi.shopkeeper.service.order.ActivityOrderService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author AdinZ
 * @date 2023/1/3 22:36
 */
@Service
public class ActivitySolitaireService extends AbsActivityService<ActivitySolitaireJpa, ActivitySolitaire, Long> {

    public ActivitySolitaireService(DispatchContext dispatchContext) {
        super(dispatchContext);
    }

    @Override
    public ActivityType getActivityType() {
        return ActivityType.SOLITAIRE;
    }

    @Override
    @Transactional
    public BasicEntity saveExpand(long aid, JSONObject data) {
        ActivitySolitaire solitaire = data.toJavaObject(ActivitySolitaire.class);
        if (solitaire == null) throw new BasicException("接龙参数错误");

        solitaire.setAid(aid);
        if (StringUtils.isEmpty(solitaire.getTitle()))
            throw new BasicException("接龙商品名字错误");
        if (StringUtils.isEmpty(solitaire.getThumb()))
            throw new BasicException("封面错误");
        if (solitaire.getStockNum() <= 0) throw new BasicException("库存数量错误");
        JSONArray items = data.getJSONArray("items");
        List<ActivitySolitaireItem> itemList = new ArrayList<>();
        if (items != null && items.size() > 0) {
            itemList = items.toJavaList(ActivitySolitaireItem.class);
            for (int i = 0; i < itemList.size(); i++) {
                itemList.get(i).setIndex(i);
                itemList.get(i).setId(null);
                itemList.get(i).setAid(aid);
                if (itemList.get(i).getCount() <= 0) throw new BasicException("接龙梯队" + (i + 1) + "参与人数错误");
                BigDecimal rate = itemList.get(i).getRate();
                if (rate == null || rate.compareTo(BigDecimal.ZERO) < 0)
                    throw new BasicException("接龙梯队" + (i + 1) + "优惠比例错误");

            }
        }

        //保存新的
        this.save(solitaire);
        if (itemList.size() > 0)
            this.dispatchContext.getServiceOne(ActivitySolitaireItemService.class).save(itemList);
        return solitaire;
    }

    @Override
    @Transactional
    public int deleteByAid(long aid) {
        Integer integer = this.repository.deleteByAid(aid);
        this.dispatchContext.getServiceOne(ActivitySolitaireItemService.class).deleteByAid(aid);
        return ResUtils.getDefault(integer);
    }

    @Override
    @Transactional
    public ActivityOrder createOrder(BasicEntity basic, Activity activity, Map<String, Long> incrementStock, CreateOrderRequest request, Token<Object> token) {
        ActivitySolitaire solitaire = (ActivitySolitaire) basic;
        int number = request.getOther().getIntValue("number");
        if (number > 0) request.setNumber(number);
        if (solitaire.getLimitNum() > 0) {
            long count = this.dispatchContext.getServiceOne(ActivityOrderService.class).count(
                    new QueryWrapper().eq("aid", activity.getId()).eq("buyerId", token.getFid())
                            .eq("statusType", 1).eq("activityType", activity.getType())
            );
            if (count >= solitaire.getLimitNum())
                throw new BasicException("超过限购数量");


        }
        //库存总数
        final int stockNum = solitaire.getStockNum();
        long total = this.dispatchContext.getServiceOne(ProductNumService.class).totalByGid(activity.getId(), AppConst.ACTIVITY_SELL_TOTAL);
        if (request.getNumber() + total > stockNum) {
            throw new BasicException("最大下单还能下单" + (solitaire.getLimitNum() - total) + "");
        }
        long increment = this.dispatchContext.getServiceOne(RedisService.class).increment(AppConst.ACTIVITY_SELL_STOCK_KEY, activity.getId(), 0L);
        if ((total + increment) >= stockNum) {
            throw new BasicException("接龙已完成");
        }
        this.dispatchContext.getServiceOne(RedisService.class).increment(AppConst.ACTIVITY_SELL_STOCK_KEY, activity.getId(), 1L);
        incrementStock.put(AppConst.ACTIVITY_STOCK_LOCK, activity.getId());
        ActivityOrder order = new ActivityOrder();
        if (request.getSugar() != null)
            order.setSugar(request.getSugar());
        order.setPrice(solitaire.getPrice());
        order.setCostPrice(activity.getPrice());
        return order;
    }

    @Override
    public BigDecimal sugarDeduction(Activity activity, BigDecimal rate, BigDecimal amount, long uid) {
        ActivitySolitaire solitaire = super.getByAid(activity.getId());
        return super.sugarDeduction(solitaire.getPrice(), rate, amount);
    }
}
